From 441c147179a2c6755c5d90de63869af612f88a66 Mon Sep 17 00:00:00 2001 From: Daniel Golle Date: Sat, 12 Jul 2025 03:01:08 +0100 Subject: [PATCH] libudev-zero: import upstream patches udev_device.c: fix TOCTOU race condition (illiliti/libudev-zero#57) illiliti/libudev-zero@a2cc51bb142c16eac5598237d2edb46f095607be Avoidable OOM on small systems (illiliti/libudev-zero#62) illiliti/libudev-zero@5eca08d71d51074bfe7b14fcf7d89318f4f6ff47 Fixes incorrect detection of touchpads (illiliti/libudev-zero#66) illiliti/libudev-zero@bbeb7ad51c1edb7ab3cf63f30a21e9bb383b7994 Signed-off-by: Daniel Golle --- libs/libudev-zero/Makefile | 2 +- ...evice.c-fix-TOCTOU-race-condition-57.patch | 59 +++++++ ...02-Avoidable-OOM-on-small-systems-62.patch | 163 ++++++++++++++++++ ...-incorrect-detection-of-touchpads-66.patch | 41 +++++ 4 files changed, 264 insertions(+), 1 deletion(-) create mode 100644 libs/libudev-zero/patches/0001-udev_device.c-fix-TOCTOU-race-condition-57.patch create mode 100644 libs/libudev-zero/patches/0002-Avoidable-OOM-on-small-systems-62.patch create mode 100644 libs/libudev-zero/patches/0003-Fixes-incorrect-detection-of-touchpads-66.patch diff --git a/libs/libudev-zero/Makefile b/libs/libudev-zero/Makefile index 0d18307bc3..e8a5cb19ac 100644 --- a/libs/libudev-zero/Makefile +++ b/libs/libudev-zero/Makefile @@ -6,7 +6,7 @@ include $(TOPDIR)/rules.mk PKG_NAME:=libudev-zero PKG_VERSION:=1.0.3 -PKG_RELEASE:=1 +PKG_RELEASE:=2 PKG_SOURCE:=$(PKG_NAME)-$(PKG_VERSION).tar.gz PKG_SOURCE_URL:=https://codeload.github.com/illiliti/libudev-zero/tar.gz/$(PKG_VERSION)? diff --git a/libs/libudev-zero/patches/0001-udev_device.c-fix-TOCTOU-race-condition-57.patch b/libs/libudev-zero/patches/0001-udev_device.c-fix-TOCTOU-race-condition-57.patch new file mode 100644 index 0000000000..4d3528d62d --- /dev/null +++ b/libs/libudev-zero/patches/0001-udev_device.c-fix-TOCTOU-race-condition-57.patch @@ -0,0 +1,59 @@ +From a2cc51bb142c16eac5598237d2edb46f095607be Mon Sep 17 00:00:00 2001 +From: Mingjie Shen +Date: Tue, 5 Dec 2023 03:41:24 -0500 +Subject: [PATCH] udev_device.c: fix TOCTOU race condition (#57) + +Separately checking the state of a file before operating on it may allow +an attacker to modify the file between the two operations. + +Reference: CWE-367. +--- + udev_device.c | 18 ++++++++++-------- + 1 file changed, 10 insertions(+), 8 deletions(-) + +--- a/udev_device.c ++++ b/udev_device.c +@@ -267,16 +267,17 @@ const char *udev_device_get_sysattr_valu + + snprintf(path, sizeof(path), "%s/%s", udev_device_get_syspath(udev_device), sysattr); + +- if (lstat(path, &st) != 0 || !S_ISREG(st.st_mode)) { +- return NULL; +- } +- + file = fopen(path, "r"); + + if (!file) { + return NULL; + } + ++ if (fstat(fileno(file), &st) != 0 || !S_ISREG(st.st_mode)) { ++ fclose(file); ++ return NULL; ++ } ++ + // TODO dynamic allocation of data + len = fread(data, 1, sizeof(data) - 1, file); + +@@ -309,16 +310,17 @@ int udev_device_set_sysattr_value(struct + + snprintf(path, sizeof(path), "%s/%s", udev_device_get_syspath(udev_device), sysattr); + +- if (lstat(path, &st) != 0 || !S_ISREG(st.st_mode)) { +- return -1; +- } +- + file = fopen(path, "w"); + + if (!file) { + return -1; + } + ++ if (fstat(fileno(file), &st) != 0 || !S_ISREG(st.st_mode)) { ++ fclose(file); ++ return -1; ++ } ++ + len = strlen(value); + + if (fwrite(value, 1, len, file) != len) { diff --git a/libs/libudev-zero/patches/0002-Avoidable-OOM-on-small-systems-62.patch b/libs/libudev-zero/patches/0002-Avoidable-OOM-on-small-systems-62.patch new file mode 100644 index 0000000000..904f41ff20 --- /dev/null +++ b/libs/libudev-zero/patches/0002-Avoidable-OOM-on-small-systems-62.patch @@ -0,0 +1,163 @@ +From 5eca08d71d51074bfe7b14fcf7d89318f4f6ff47 Mon Sep 17 00:00:00 2001 +From: liamHowatt <30486941+liamHowatt@users.noreply.github.com> +Date: Tue, 5 Dec 2023 04:15:26 -0500 +Subject: [PATCH] Avoidable OOM on small systems (#62) + +* bandaid fix OOM + +* refactor fix OOM + +* Makefile: remove no longer needed -pthread option + +* libudev.pc.in: remove threads requirement + +--------- + +Co-authored-by: illiliti +--- + Makefile | 2 +- + libudev.pc.in | 1 - + udev_enumerate.c | 65 +++++++++++------------------------------------- + 3 files changed, 15 insertions(+), 53 deletions(-) + +--- a/Makefile ++++ b/Makefile +@@ -5,7 +5,7 @@ PREFIX = /usr/local + LIBDIR = ${PREFIX}/lib + INCLUDEDIR = ${PREFIX}/include + PKGCONFIGDIR = ${LIBDIR}/pkgconfig +-XCFLAGS = ${CPPFLAGS} ${CFLAGS} -std=c99 -fPIC -pthread -D_XOPEN_SOURCE=700 \ ++XCFLAGS = ${CPPFLAGS} ${CFLAGS} -std=c99 -fPIC -D_XOPEN_SOURCE=700 \ + -Wall -Wextra -Wpedantic -Wmissing-prototypes -Wstrict-prototypes \ + -Wno-unused-parameter + XLDFLAGS = ${LDFLAGS} -shared -Wl,-soname,libudev.so.1 +--- a/libudev.pc.in ++++ b/libudev.pc.in +@@ -9,5 +9,4 @@ Description: Daemonless replacement for + Version: @VERSION@ + URL: https://github.com/illiliti/libudev-zero + Libs: -L${libdir} -ludev +-Libs.private: -pthread + Cflags: -I${includedir} +--- a/udev_enumerate.c ++++ b/udev_enumerate.c +@@ -21,7 +21,6 @@ + #include + #include + #include +-#include + + #include "udev.h" + #include "udev_list.h" +@@ -38,13 +37,6 @@ struct udev_enumerate { + int refcount; + }; + +-struct udev_enumerate_thread { +- struct udev_enumerate *udev_enumerate; +- pthread_mutex_t *mutex; +- char path[PATH_MAX]; +- pthread_t thread; +-}; +- + int udev_enumerate_add_match_subsystem(struct udev_enumerate *udev_enumerate, const char *subsystem) + { + return udev_enumerate ? !!udev_list_entry_add(&udev_enumerate->subsystem_match, subsystem, NULL, 0) - 1 : -1; +@@ -231,31 +223,27 @@ static int filter_sysattr(struct udev_en + return 1; + } + +-static void *add_device(void *ptr) ++static void add_device(struct udev_enumerate *udev_enumerate, const char *path) + { +- struct udev_enumerate_thread *thread = ptr; + struct udev_device *udev_device; + +- udev_device = udev_device_new_from_syspath(thread->udev_enumerate->udev, thread->path); ++ udev_device = udev_device_new_from_syspath(udev_enumerate->udev, path); + + if (!udev_device) { +- return NULL; ++ return; + } + +- if (!filter_subsystem(thread->udev_enumerate, udev_device) || +- !filter_sysname(thread->udev_enumerate, udev_device) || +- !filter_property(thread->udev_enumerate, udev_device) || +- !filter_sysattr(thread->udev_enumerate, udev_device)) { ++ if (!filter_subsystem(udev_enumerate, udev_device) || ++ !filter_sysname(udev_enumerate, udev_device) || ++ !filter_property(udev_enumerate, udev_device) || ++ !filter_sysattr(udev_enumerate, udev_device)) { + udev_device_unref(udev_device); +- return NULL; ++ return; + } + +- pthread_mutex_lock(thread->mutex); +- udev_list_entry_add(&thread->udev_enumerate->devices, udev_device_get_syspath(udev_device), NULL, 0); +- pthread_mutex_unlock(thread->mutex); ++ udev_list_entry_add(&udev_enumerate->devices, udev_device_get_syspath(udev_device), NULL, 0); + + udev_device_unref(udev_device); +- return NULL; + } + + static int filter_dot(const struct dirent *de) +@@ -265,9 +253,7 @@ static int filter_dot(const struct diren + + static int scan_devices(struct udev_enumerate *udev_enumerate, const char *path) + { +- struct udev_enumerate_thread *thread; +- pthread_mutex_t mutex; +- int i, cnt, ret = 1; ++ int i, cnt; + struct dirent **de; + + cnt = scandir(path, &de, filter_dot, NULL); +@@ -276,41 +262,18 @@ static int scan_devices(struct udev_enum + return 0; + } + +- thread = calloc(cnt, sizeof(*thread)); +- +- if (!thread) { +- ret = 0; +- goto free_de; +- } +- +- pthread_mutex_init(&mutex, NULL); +- +- for (i = 0; i < cnt; i++) { +- thread[i].mutex = &mutex; +- thread[i].udev_enumerate = udev_enumerate; +- +- snprintf(thread[i].path, sizeof(thread[i].path), "%s/%s", path, de[i]->d_name); +- +- if (pthread_create(&thread[i].thread, NULL, add_device, &thread[i]) != 0) { +- ret = 0; +- break; +- } +- } +- + for (i = 0; i < cnt; i++) { +- pthread_join(thread[i].thread, NULL); ++ char device_path[PATH_MAX]; ++ snprintf(device_path, sizeof(device_path), "%s/%s", path, de[i]->d_name); ++ add_device(udev_enumerate, device_path); + } + +- free(thread); +- pthread_mutex_destroy(&mutex); +- +-free_de: + for (i = 0; i < cnt; i++) { + free(de[i]); + } + + free(de); +- return ret; ++ return 1; + } + + int udev_enumerate_scan_devices(struct udev_enumerate *udev_enumerate) diff --git a/libs/libudev-zero/patches/0003-Fixes-incorrect-detection-of-touchpads-66.patch b/libs/libudev-zero/patches/0003-Fixes-incorrect-detection-of-touchpads-66.patch new file mode 100644 index 0000000000..1884192d18 --- /dev/null +++ b/libs/libudev-zero/patches/0003-Fixes-incorrect-detection-of-touchpads-66.patch @@ -0,0 +1,41 @@ +From bbeb7ad51c1edb7ab3cf63f30a21e9bb383b7994 Mon Sep 17 00:00:00 2001 +From: Matt +Date: Tue, 13 Feb 2024 11:20:52 +0000 +Subject: [PATCH] Fixes incorrect detection of touchpads (#66) + +Some touchpad drivers (such as applespi) claim to have both EV_ABS and EV_REL +capabilities. These touchpads are then reported as mice by libudev-zero. +--- + udev_device.c | 14 +++++++------- + 1 file changed, 7 insertions(+), 7 deletions(-) + +--- a/udev_device.c ++++ b/udev_device.c +@@ -458,13 +458,7 @@ static void set_properties_from_evdev(st + udev_list_entry_add(&udev_device->properties, "ID_INPUT_SWITCH", "1", 0); + } + +- if (test_bit(ev_bits, EV_REL)) { +- if (test_bit(rel_bits, REL_Y) && test_bit(rel_bits, REL_X) && +- test_bit(key_bits, BTN_MOUSE)) { +- udev_list_entry_add(&udev_device->properties, "ID_INPUT_MOUSE", "1", 0); +- } +- } +- else if (test_bit(ev_bits, EV_ABS)) { ++ if (test_bit(ev_bits, EV_ABS)) { + if (test_bit(key_bits, BTN_SELECT) || test_bit(key_bits, BTN_TR) || + test_bit(key_bits, BTN_START) || test_bit(key_bits, BTN_TL)) { + if (test_bit(key_bits, BTN_TOUCH)) { +@@ -494,6 +488,12 @@ static void set_properties_from_evdev(st + } + } + } ++ else if (test_bit(ev_bits, EV_REL)) { ++ if (test_bit(rel_bits, REL_Y) && test_bit(rel_bits, REL_X) && ++ test_bit(key_bits, BTN_MOUSE)) { ++ udev_list_entry_add(&udev_device->properties, "ID_INPUT_MOUSE", "1", 0); ++ } ++ } + + if (!test_bit(ev_bits, EV_KEY)) { + return; -- 2.30.2